from library import respberrypi

# 数据地址自动增加的模式
VK1640B_CMD_DATA_AUTO = 0x40
# 固定地址写数据模式
VK1640B_CMD_DATA_FIXED = 0x44
# 显示地址
VK1640B_CMD_ADDRESS = 0xC0
# 显示控制命令
VK1640B_CMD_DISPLAY = 0x8F
# 字节长度
BYTE_LENGTH = 8
# 数据地址 GPIO2 SDA
DATA_PIN = 2
# 数据地址 GPIO3 SCL
CLOCK_PIN = 3


def start():
    respberrypi.gpio_output(CLOCK_PIN, respberrypi.SIG_HIGH)
    respberrypi.gpio_output(DATA_PIN, respberrypi.SIG_LOW)


def stop():
    respberrypi.gpio_output(CLOCK_PIN, respberrypi.SIG_HIGH)
    respberrypi.gpio_output(DATA_PIN, respberrypi.SIG_HIGH)


def send(data):
    """
    发送数据，一位一位发送
    :param data: 一个字节
    :return: void
    """
    for _ in range(BYTE_LENGTH):
        respberrypi.gpio_output(CLOCK_PIN, respberrypi.SIG_LOW)
        respberrypi.gpio_output(DATA_PIN, respberrypi.SIG_HIGH if data & 1 else respberrypi.SIG_LOW)
        data = data >> 1
        respberrypi.gpio_output(CLOCK_PIN, respberrypi.SIG_HIGH)


def send_data(data, address=None):
    if address is not None:
        send(VK1640B_CMD_ADDRESS | address)
    send(data)


def send_command(cmd):
    start()
    send_data(cmd)
    stop()


def send_fixed_address_data(data_packages):
    """
    发送数据
    模式：固定地址模式
    :param data_packages: example: [(0, 0x00), (1, 0x11)]   ->   (0, 0x00) 前面代表位置，后面代表数据
    :return: void
    """
    # 1. 发固定地址指令
    send_command(VK1640B_CMD_DATA_FIXED)
    # 2. 发地址 + 发数据
    for data_package in data_packages:
        start()
        send_data(data_package[1], data_package[0])
        stop()
    # 3. 发显示指令
    send_command(VK1640B_CMD_DISPLAY)


def send_auto_address_data(data_packages):
    """
    发送数据
    模式：地址自动增加模式
    :param
    data_packages: example: [0x00, 0x11]
    :return: void
    """
    # 1. 发固定地址指令
    send_command(VK1640B_CMD_DATA_AUTO)
    # 2. 发地址 + 发数据
    start()
    send(VK1640B_CMD_ADDRESS)
    for data in data_packages:
        send_data(data)
    stop()
    # 3. 发显示指令
    send_command(VK1640B_CMD_DISPLAY)


def clear_display(size):
    """
    清理屏幕
    :param size: 屏幕大小
    :return: void
    """
    data_packages = [0x00] * size
    send_auto_address_data(data_packages)


def init(data_channel=None, clock_channel=None):
    global DATA_PIN
    global CLOCK_PIN
    if data_channel is not None:
        DATA_PIN = data_channel
    if clock_channel is not None:
        CLOCK_PIN = clock_channel
    respberrypi.gpio_init(out_channels=[[DATA_PIN, respberrypi.SIG_HIGH], [CLOCK_PIN, respberrypi.SIG_HIGH]])


def cleanup():
    respberrypi.gpio_cleanup([DATA_PIN, CLOCK_PIN])
